<?php

namespace App\Service\EasyWechat;

use App\Exceptions\ApiException;
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
use EasyWeChat\OfficialAccount\Application;
use EasyWeChat\OfficialAccount\Server;
use EasyWeChat\OfficialAccount\Utils;
use Exception;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
use Overtrue\Socialite\Contracts\ProviderInterface;
use ReflectionException;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Throwable;

class OfficialAccountService
{

    protected array     $config;      // 配置
    private Application $app;         // 公众号实例
    protected string    $accessToken; // 公众号access_token

    public string $paySuccessTemplateId; // 支付成功模板消息id

    public string $refundSuccessTemplateId; // 退款成功模板消息id


    /**
     * @throws ApiException
     */
    public function __construct()
    {
        $config       = [
            'app_id'  => 'app_id',
            'secret'  => 'app_secret',
            'token'   => 'token',
            'aes_key' => 'aes_key',

            /**
             * OAuth 配置
             * scopes：公众平台（snsapi_userinfo / snsapi_base），开放平台：snsapi_login
             * callback：OAuth授权完成后的回调页地址
             */
            'oauth'   => [
                'scopes'   => ['snsapi_base'],
                'callback' => '/examples/oauth_callback.php',
            ],

            /**
             * 接口请求相关配置，超时时间等，具体可用参数请参考：
             * https://github.com/symfony/symfony/blob/5.3/src/Symfony/Contracts/HttpClient/HttpClientInterface.php
             */
            'http'    => [
                'timeout' => 5.0,
                // 'base_uri' => 'https://api.weixin.qq.com/', // 如果你在国外想要覆盖默认的 url 的时候才使用，根据不同的模块配置不同的 uri

                'retry' => true, // 使用默认重试配置
                //  'retry' => [
                //      // 仅以下状态码重试
                //      'status_codes' => [429, 500]
                //       // 最大重试次数
                //      'max_retries' => 3,
                //      // 请求间隔 (毫秒)
                //      'delay' => 1000,
                //      // 如果设置，每次重试的等待时间都会增加这个系数
                //      // (例如. 首次:1000ms; 第二次: 3 * 1000ms; etc.)
                //      'multiplier' => 3
                //  ],
            ],
        ];
        $this->config = $config;

        // 实例化公众号
        try {
            $this->app = new Application($config);
            $this->app->setCache(Cache::store('redisCommon'));
            $this->accessToken = $this->app->getAccessToken()->getToken();
            $this->paySuccessTemplateId    = '5pEIXhwcrXgBLkaeA9sMPM_Rdxz6bk51KE6YgWk4ocw';
            $this->refundSuccessTemplateId = 'ZXrACxER9yY5O__zgZ18YXHIhMGVlnNltxOUYeG3f70';
        } catch (InvalidArgumentException $e) {
            throw new ApiException($e->getMessage());
        }

    }

    /**
     * 获取服务端对象
     *
     * @return Server|\EasyWeChat\Kernel\Contracts\Server
     * @throws Exception
     */
    public function getServer(): Server|\EasyWeChat\Kernel\Contracts\Server
    {
        try {
            return $this->app->getServer();
        } catch (InvalidArgumentException|ReflectionException|Throwable $e) {
            throw new Exception($e->getMessage());
        }
    }

    /**
     * 获取网页授权
     *
     * @return ProviderInterface
     * @throws Exception
     */
    public function getOAuth(): ProviderInterface
    {
        try {
            return $this->app->getOAuth();
        } catch (InvalidArgumentException $e) {
            throw new Exception($e->getMessage());
        }
    }

    /**
     * 获取工具类
     *
     * @return Utils
     */
    public function getUtils(): Utils
    {
        return $this->app->getUtils();
    }

    /**
     * 创建菜单
     *
     * @return void
     */
    public function menuCreate(): void
    {
        $api     = $this->app->getClient();
        $buttons = [
            [
                "name"       => "商户中心",
                "sub_button" => [
                    [
                        'type' => 'view',
                        'name' => '商户中心',
                        'url'  => 'https://web.soezpay.com/#/loginSign?wx_user=1',
                    ],
                    [
                        'type' => 'view',
                        'name' => '联系客服',
                        'url'  => 'https://work.weixin.qq.com/kfid/kfcfc331efa03feb4e9',
                    ],
                ],
            ],
            [
                "type" => "view",
                "name" => "商户绑定",
                "url"  => 'https://web.soezpay.com/#/login?wx_user=1',
            ],
            [
                "name"       => "商户入网",
                "sub_button" => [
                    [
                        'type' => 'view',
                        'name' => '商户入网',
                        'url'  => 'https://web.soezpay.com/#/MerchantApp?id=1&wx_user=1',
                    ],
                    [
                        'type' => 'view',
                        'name' => '进件列表',
                        'url'  => 'https://web.soezpay.com/#/MerchantApp?id=2&wx_user=1',
                    ],
                    [
                        'type' => 'view',
                        'name' => '商户投诉',
                        'url'  => 'https://web.soezpay.com/#/complaintLogin?wx_user=1&from=1',
                    ],
                ],
            ],
        ];
        try {
            $response = $api->postJson('/cgi-bin/menu/create', [
                'body' => json_encode([
                    'button' => $buttons,
                ], JSON_UNESCAPED_UNICODE),
            ]);
            if ($response->isFailed()) {
                throw new Exception($response['errmsg']);
            }
            echo "<pre>";
            var_dump($response->getContent());
            die;
        } catch (Exception|ClientExceptionInterface|RedirectionExceptionInterface|ServerExceptionInterface|TransportExceptionInterface$e) {
            echo "<pre>";
            var_dump(1);
            var_dump($e->getMessage());
            die;
        }
    }

    /**
     * 菜单信息
     *
     * @return void
     */
    public function menuInfo(): void
    {
        $api = $this->app->getClient();
        try {
            $response = $api->get('/cgi-bin/get_current_selfmenu_info');
            if ($response->isFailed()) {
                throw new Exception($response['errmsg']);
            }
            echo "<pre>";
            var_dump($response->getContent());
            die;
        } catch (Exception|ClientExceptionInterface|RedirectionExceptionInterface|ServerExceptionInterface|TransportExceptionInterface$e) {
            echo "<pre>";
            var_dump(1);
            var_dump($e->getMessage());
            die;
        }
    }

    /**
     * 菜单删除
     *
     * @return void
     */
    public function menuDel(): void
    {
        $api = $this->app->getClient();
        try {
            $response = $api->get('/cgi-bin/menu/delete');
            if ($response->isFailed()) {
                throw new Exception($response['errmsg']);
            }
            echo "<pre>";
            var_dump($response->getContent());
            die;
        } catch (Exception|ClientExceptionInterface|RedirectionExceptionInterface|ServerExceptionInterface|TransportExceptionInterface$e) {
            echo "<pre>";
            var_dump(1);
            var_dump($e->getMessage());
            die;
        }
    }

    /**
     * 发送模板消息
     *
     * @param $data
     * @return string
     * @throws Exception
     */
    public function templateMessage($data): string
    {
        $api = $this->app->getClient();
        try {
            $response = $api->postJson('/cgi-bin/message/template/send', [
                'body' => json_encode($data, JSON_UNESCAPED_UNICODE),
            ]);
            if ($response->isFailed()) {
                throw new Exception($response['errmsg']);
            }
            Log::info('公众号推送结果', (array)$response);
            return $response->getContent();
        } catch (Exception|ClientExceptionInterface|RedirectionExceptionInterface|ServerExceptionInterface|TransportExceptionInterface $e) {
            throw new Exception($e->getMessage());
        }
    }

    /**
     * 获取设置的行业信息
     *
     * @return void
     */
    public function getIndustry(): void
    {
        $api = $this->app->getClient();
        try {
            $response = $api->get('/cgi-bin/template/get_industry');
            if ($response->isFailed()) {
                throw new Exception($response['errmsg']);
            }
            echo "<pre>";
            var_dump($response->getContent());
            die;
        } catch (Exception|ClientExceptionInterface|RedirectionExceptionInterface|ServerExceptionInterface|TransportExceptionInterface$e) {
            echo "<pre>";
            var_dump(1);
            var_dump($e->getMessage());
            die;
        }
    }
}
